package me.keiwu.task.controller;

import com.alibaba.fastjson.JSONObject;
import me.keiwu.pub.data.ConfigType;
import me.keiwu.pub.data.Response;
import me.keiwu.pub.data.config.ChallengeConfigBean;
import me.keiwu.pub.util.CacheUtil;
import me.keiwu.pub.util.ContextUtil;
import me.keiwu.pub.util.DateUtil;
import me.keiwu.task.domain.Challenge;
import me.keiwu.task.rpc.UserRpc;
import me.keiwu.task.service.ChallengeService;
import me.keiwu.task.util.enums.ChallengeState;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * Created by kei on 06/11/2017.
 */
@RestController
@RequestMapping("/challenge")
public class ChallengeController {


    @Autowired
    private ChallengeService challengeService;
    @Autowired
    private UserRpc userRpc;
    @Autowired
    private CacheUtil cacheUtil;



    @RequestMapping("/list")
    @ResponseBody
    public Response list(HttpServletRequest request,
                         @RequestParam(defaultValue = "0") Integer page,
                         @RequestParam(defaultValue = "10") Integer size) {
        Long userId = ContextUtil.getLoginUserId(request);
        Page<Challenge> list = challengeService.findUserStartingChallenges(userId, page, size);
        Date now = new Date();
        list.getContent().forEach(c -> this.updateState(now, c));
        return Response.ok(list);
    }

    @RequestMapping("/list/other")
    @ResponseBody
    public Response listOther(HttpServletRequest request,
                              @RequestParam(defaultValue = "0") Integer page,
                              @RequestParam(defaultValue = "10") Integer size) {
        Long userId = ContextUtil.getLoginUserId(request);
        Page<Challenge> list = challengeService.findOtherChallenges(userId, page, size);
        Date now = new Date();
        list.getContent().forEach(c -> this.updateState(now, c));
        return Response.ok(list);
    }

    @RequestMapping("/create")
    @ResponseBody
    public Response create(HttpServletRequest request,
                           String name,
                           String endDate,
                           @RequestParam(required = false) Long challenger,
                           @RequestParam(required = false) String startDate,
                           @RequestParam(defaultValue = "yyyy-MM-dd HH:mm:ss") String pattern) {
        Long userId = ContextUtil.getLoginUserId(request);
        Date end = DateUtil.parseDate(endDate, pattern);
        Date start;
        if (end == null) return Response.fail("时间格式不正确");
        if (StringUtils.isNotBlank(startDate)) {
            start = DateUtil.parseDate(startDate, pattern);
            if (start == null) return Response.fail("时间格式不正确");
        } else {
            start = DateUtil.getDayStart(new Date());
        }
        if (start.after(end)) return Response.fail("时间不正确");

        ChallengeConfigBean taskConfig = cacheUtil.getConfig(ConfigType.CHALLENGE_CONFIG, ChallengeConfigBean.class);
        if (taskConfig == null) return Response.fail("缺少任务配置");
        if (DateUtil.getMinuteOfDay(new Date()) > taskConfig.getStopChallengeTime()) return Response.ok("当前时间不能发起挑战，请明天再来吧！");


        if (!challengeService.checkCanChallenge(userId, challenger, start, end))
            return Response.fail("你与该用户已有一场正在进行中的挑战，不可重复对战哦");

        Challenge challenge = challengeService.createChallenge(userId, challenger, name, start, end);
        if (challenge == null) return Response.fail("星币不足");
        return Response.ok(challenge);
    }

    @RequestMapping("/reply")
    @ResponseBody
    public Response reply(HttpServletRequest request, Long challengeId, Integer state) {
        // 回复者为被邀请者
        Long invitee = ContextUtil.getLoginUserId(request);
        return challengeService.replyChallenge(challengeId, invitee, state);
    }

    @RequestMapping("/award")
    @ResponseBody
    public Response award(HttpServletRequest request, Long challengeId) {
        Long userId = ContextUtil.getLoginUserId(request);
        return challengeService.awardChallenge(userId, challengeId);
    }


    @RequestMapping("/award/all")
    @ResponseBody
    public Response awardAll(HttpServletRequest request) {
        Long userId = ContextUtil.getLoginUserId(request);
        return challengeService.awardAllChallenge(userId);
    }


    @RequestMapping("/detail")
    @ResponseBody
    public Response detail(Long challengeId) {
        Challenge challenge = challengeService.getByChallengeId(challengeId);
        this.updateState(new Date(), challenge);
        JSONObject json = new JSONObject();
        json.put("challenge", challenge);
        json.put("initiatorAchievement", challengeService.getAchievement(challenge.getInitiator()));
        json.put("initiatorRank", cacheUtil.getUserRank(challenge.getInitiator()));
        if (challenge.getChallenger() != null) {
            json.put("challengerAchievement", challengeService.getAchievement(challenge.getChallenger()));
            json.put("challengerRank", cacheUtil.getUserRank(challenge.getChallenger()));
            json.put("hasComment", userRpc.hasComment(challenge.getInitiator(), challenge.getChallenger()));
        }
        return Response.ok(json);
    }



    @RequestMapping("/achievement")
    @ResponseBody
    public Response achievement(HttpServletRequest request,
                               @RequestParam(defaultValue = "0") Integer page,
                               @RequestParam(defaultValue = "10") Integer size) {
        Long userId = ContextUtil.getLoginUserId(request);
        JSONObject json = new JSONObject();
        Date now = new Date();
        Page<Challenge> challenges = challengeService.findUserEndChallenges(userId, page, size);
        challenges.forEach(c -> this.updateState(now, c));
        json.put("challenges", challenges);
        json.put("achievement", challengeService.getAchievement(userId));
        return Response.ok(json);
    }


    @RequestMapping("/achievement/other")
    @ResponseBody
    public Response achievement(HttpServletRequest request, Long userId) {
        Long loginId = ContextUtil.getLoginUserId(request);
        JSONObject json = new JSONObject();
        json.put("achievement", challengeService.getAchievement(userId));
        json.put("hasChallenged", challengeService.checkHasChallenge(loginId, userId));
        json.put("userInfo", userRpc.userInfo(userId));
        json.put("hasComment", userRpc.hasComment(loginId, userId));
        return Response.ok(json);
    }

    private void updateState(Date now, Challenge c) {
        Date dayEnd = DateUtil.getDayEnd(c.getEndDate());
        if (c.getChallenger() == null && now.after(dayEnd)) {
            c.setState(ChallengeState.OVERTIME.getState());
        } else if (now.after(dayEnd)) {
            c.setState(ChallengeState.END.getState());
        }
    }

}
